package com.hycloud.cloudstack.common;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.URI;
import java.util.Collection;
import java.util.Map;

import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.HttpClients;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import com.fasterxml.jackson.core.JsonParseException;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.ObjectMapper;

@Service
public class CloudstackApi {

	private Logger logger = LoggerFactory.getLogger(CloudstackApi.class);

	private String REQUEST_PATH = "/client/api";
	@Value("${cloudstack.ip}")
	private String ip;
	@Value("${cloudstack.port}")
	private int port;
	@Value("${cloudstack.publicIp}")
	private String publicIp;
	@Value("${cloudstack.apiKey}")
	private String apiKey;
	@Value("${cloudstack.secretKey}")
	private String secretKey;

	/**
	 * cloudstack API
	 * 
	 * @param request
	 * @return
	 * @throws Exception
	 */
	public String api(Map<String, String> params) throws Exception {
		return new ObjectMapper().writeValueAsString(mapData(params));
	}

	public <T> T api(Map<String, String> params, String attr, Class<T> valueType)
			throws JsonParseException, JsonMappingException, JsonProcessingException, IOException, Exception {
		ObjectMapper mapper = new ObjectMapper();
		T result = mapper.readValue(mapper.writeValueAsString(mapData(params).get(attr)), valueType);
		return result;
	}

	public Map<String, Object> mapData(Map<String, String> params) throws Exception {
		String command = params.get("command");

		if (command == null) {
			return null;
		} else {
			String path = "http://" + ip + ":" + port + REQUEST_PATH + "?command=" + command;
			String url = CsSignature.url(path, apiKey, secretKey, params);
			logger.info("调用cloudstack api:" + url);
			String result = executeGet(url);
			logger.info("cloudstack api返回:" + result);
			ObjectMapper mapper = new ObjectMapper();
			Map<String, Object> map = mapper.readValue(result, Map.class);
			String key = (command + "response").toLowerCase();
			map = (Map<String, Object>) map.get(key);
			if (map.containsKey("errorcode")) {
				Integer errorcode = (Integer) map.get("errorcode");
				String errortext = (String) map.get("errortext");
				throw new CloudstackApiException(errorcode, errortext);
			}
			return map;
		}
	}

	@SuppressWarnings("finally")
	private String executeGet(String url) throws Exception {
		BufferedReader in = null;

		String content = null;
		try {
			// 定义HttpClient
			HttpClient client = HttpClients.createDefault();
			// 实例化HTTP方法
			HttpGet request = new HttpGet();
			request.setURI(new URI(url));
			HttpResponse response = client.execute(request);

			in = new BufferedReader(new InputStreamReader(response.getEntity().getContent()));
			StringBuffer sb = new StringBuffer("");
			String line = "";
			String NL = System.getProperty("line.separator");
			while ((line = in.readLine()) != null) {
				sb.append(line + NL);
			}
			in.close();
			content = sb.toString();
		} finally {
			if (in != null) {
				try {
					if (in != null) {
						in.close();
					} // 最后要关闭BufferedReader
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
			return content;
		}
	}

}
